package com.source.utils;

import com.alibaba.excel.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.util.UUID;
/**
 * @author fengq
 */

@Slf4j
public class ImageUtils{

    /**
     * 文件保存的路径 user\local\image\imageCatalogueEnum.目录名\图片名
     */
    public static final String IMAGE_PATH= File.separator+"user"+ File.separator+"lightfowl"+ File.separator+"image"+File.separator;

    /**
     * saveImage 方法重载
     * @param multipartFile 前端上传过来文件流
     * @param imageCatalogueEnum 自定义存放文件目录说明
     * @return
     * @throws Exception
     */
    public static String saveImage(MultipartFile multipartFile, ImageCatalogueEnum imageCatalogueEnum) throws Exception {
        File upload = ImageUtils.multipartFileToFile(multipartFile);
        //处理上传的文件
        String fileName = save(upload,imageCatalogueEnum);
        //6.返回图片名字
        return "/image/"+imageCatalogueEnum.getCatalogue()+"/"+fileName;
    }

    /**
     * saveImage  方法重载
     * @param upload 文件流
     * @param catalogue  自定义存放文件的目录说明
     * @return
     */
    public static String saveImage(File upload ,ImageCatalogueEnum catalogue){
        //处理上传的文件
        String fileName = save(upload,catalogue);
        //6.返回图片名字
        return "/image/"+catalogue.getCatalogue()+"/"+fileName;
    }


    /**
     * save 保存图片并返回一个虚拟路径 保存到数据库
     * @param upload 文件流
     * @param catalogue  自定义存放文件的目录说明
     * @return
     */
    private static String save(File upload,ImageCatalogueEnum catalogue) {
        String fileName = "";
        if(upload!=null){
            log.info(">>>>>>>>>>1.获取文件扩展名");
            String uploadFileName = upload.getName();
            int index = uploadFileName.lastIndexOf(".");
            String exName = uploadFileName.substring(index);
            log.info(">>>>>>>>>>2.随机生成文件名");
            String uuid = UUID.randomUUID().toString().substring(0,8);
            log.info(">>>>>>>>>>3.拼接扩展名");
            fileName = uuid + exName;
            log.info(">>>>>>>>>>4.生成服务器文件位置");
            File imagePath = new File(ImageUtils.IMAGE_PATH+catalogue.getCatalogue());
            if (!imagePath.exists()){
                log.info(">>>>>>>>>>文件目录不存在，开始创建新的目录");
                imagePath.mkdirs();
            }
            File file = new File(ImageUtils.IMAGE_PATH+catalogue.getCatalogue()+ File.separator+fileName);
            try {
                log.info("保存的地址："+ImageUtils.IMAGE_PATH+catalogue.getCatalogue()+ File.separator+fileName);
                Files.copy(upload.toPath(),file.toPath());
                upload.delete();
                log.info(">>>>>>>>>>5.图片保存成功<<<<<<<<<<<<");
            } catch (IOException e) {
                log.info(">>>>>>>>>>图片保存异常<<<<<<<<<<<");
            }
        }
        return fileName;
    }

    /**
     * delete 删除照片，删除服务器中图片
     * @param path
     */
    public static Boolean delete(String path){
        log.info(">>>>>>>>>>>删除图片");
        String[] split = path.split("/");
        String name = split[split.length - 1];
        String catalogue=split[split.length - 2];
        File file = new File(IMAGE_PATH +catalogue+File.separator+name);
        try {
            Files.delete(file.toPath());
            return true;
        } catch (IOException e) {
            log.info(">>>>>>>>>>>删除图片出错<<<<<<<<<<<");
            e.printStackTrace();
            return false;
        }
    }


    /**
     *multipartFileToFile 将MultipartFile转换为File
     * @param multipartFile
     * @return File toFile
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile multipartFile ) throws Exception {
        File toFile = null;
        if(multipartFile.equals("")||multipartFile.getSize()<=0){
            multipartFile = null;
        }else {
            InputStream ins = null;
            ins = multipartFile.getInputStream();
            toFile = new File(multipartFile.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    /**
     * inputStreamToFile 将InputStream转换出来的资源写入到一个指定的file文件
     * @param ins
     * @param file
     */
    public static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            BufferedInputStream bis=new BufferedInputStream(ins);
            BufferedOutputStream bos=new BufferedOutputStream(os);
            int bytesRead = 0;
            while ((bytesRead = bis.read()) != -1) {
                bos.write(bytesRead);
                bos.flush();
            }
            bos.close();
            bis.close();
            os.close();
            ins.close();
        } catch (Exception e) {
            log.info(">>>>>>>>>.inputStreamToFile 方法中文件读入出错<<<<<<<<<<<<");
            e.printStackTrace();

        }
    }

    /**
     * JudgeSaveAndRemoveImage 判断是否存在照片，
     *  如果存在 ，删除旧图片，再上传图片
     *  如果不存在，开始上传图片
     * @param Path
     * @param imageCatalogueEnum
     * @return
     * @throws Exception
     */
    public static String  RemoveAndSaveImage(MultipartFile multipartFile,String Path,ImageCatalogueEnum imageCatalogueEnum) throws Exception {
        if (StringUtils.isEmpty(Path)||Path==null){
            log.info(">>>>>>>>>图片上传开始");
        }else {
            log.info(">>>>>>>>>开始删除旧的图片");
            if (!ImageUtils.delete(Path)){
                return null;
            }
        }
        return  ImageUtils.saveImage(multipartFile,imageCatalogueEnum);
    }

    /**
     * selectCatalogue 选择模块的枚举类
     * @param value
     * @return ImageCatalogueEnum
     */
    public static ImageCatalogueEnum  selectCatalogue(Integer value){
        switch (value){
            case 0: return ImageCatalogueEnum.BarcodeMachine_Catalogue;
            case 1: return ImageCatalogueEnum.SlaughterHouse_Catalogue;
            case 2: return ImageCatalogueEnum.User_Catalogue;
            case 3: return ImageCatalogueEnum.Stalls_Catalogue;
            case 4: return ImageCatalogueEnum.ToMarketMarkCode_Catalogue;
            case 5: return ImageCatalogueEnum.ToMarketStallCode_Catalogue;
            case 6: return ImageCatalogueEnum.BarcodeMachine_Repair;
            default:return null;
        }
    }


}
